#include "queue.h"

queue_t queue_init(int size){
    queue_t queue_;
    queue_.base = (queue_elem_t**)calloc(size, sizeof(queue_elem_t*));
    queue_.front = queue_.base;
    queue_.back = queue_.front;
    queue_.size = size;
    queue_.length = 0;
    return queue_;
}

queue_t queue(){
    return queue_init(QUEUE_INIT_SIZE);
}

int queue_len(queue_t s){
#if 0
    return back - front;
#else
    return s.length;
#endif
}

void debug_queue(queue_t s){
    // 自队列头遍历
    queue_elem_t **elem = s.front;
    while(elem != s.back){
        debug_cstr((*elem)[0]);
        elem++;
    }
}

void queue_push(queue_t *s, queue_elem_t *data){
    if(s->length >= s->size){
        s->base = (queue_elem_t**)realloc(s->base, s->size + QUEUE_INCREMENT);
        s->size += QUEUE_INCREMENT;
    }
    *(s->back) = data;
    if(s->back == s->base + s->size - 1){
        s->back = s->base;
    }else
        s->back++;
    s->length += 1;
}

queue_elem_t queue_pop(queue_t *s){
    assert(s->length);
    queue_elem_t **p_data = s->front;
    if(s->front == s->base + s->size -1){
        s->front = s->base;
    }else
        s->front++;
    s->length -= 1;
    return **p_data;
}

queue_elem_t queue_front(queue_t s){
    assert(s.length);
    return **s.front;
}

queue_elem_t queue_back(queue_t s){
    assert(s.length);
    return **(s.back-1);
}

void queue_free(queue_t *s){
    free(s->base);
    s->base = nullptr;
    s->front = nullptr;
    s->back = nullptr;
    s->length = 0;
    s->size = 0;
}
